import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

/*
 * Class for selection
 * and projection logic
 * that is query logic.
 */
public class Selection {

	String[] temp;
	int length;
	int record_length;
	datatype[] datatypes = new datatype[7];

	//Converting operators to codes
	public String calcop(String temp) throws Exception
	{
		if(temp.equals("="))
			return 0+"";
		else if(temp.equals("<>"))
			return 1+""+2+"";
		else if(temp.equals(">"))
			return 1+"";
		else if(temp.equals("<"))
			return 2+"";
		else if(temp.equals("<="))
			return 20+"";
		else if (temp.equals(">="))
			return 10+"";

		throw new Exception("Invalid operator");

	}
	//Function to perform to evaluate the query
	public void select(String[] array, String output)
	{
		datatypes[0] = new i1();
		datatypes[1] = new i2();
		datatypes[2] = new i4();
		datatypes[3] = new i8();
		datatypes[4] = new r4();
		datatypes[5] = new r8();
		datatypes[6] = new cx();
		String path = array[0];
		
		//Reading header of the heap file containing the schema information.
		ReadHeader readHeader = new ReadHeader();
		try 
		{
			temp = readHeader.read(path);
		} 
		catch (Exception e) 
		{	
			System.out.println(e);
		}
		length =  temp.length;
		record_length = Integer.parseInt(temp[length-1]);
		//System.out.println(record_length);
		String[] header=new String[length-1];
		for(int i=0;i<header.length;i++)
			header[i]=temp[i];
		
		//Converting header into a code
		ArrayList<datatype> headerData=convertHeader.convertHeader(header);
		heap.f=new File(path);
		boolean project[]=new boolean[headerData.size()];
		ArrayList <ArrayList<String>> select= new ArrayList<ArrayList<String>>();
		//Storing the selection and projection condition.
		try
		{
			for(int y=0;y<headerData.size();y++)
			{
				select.add(new ArrayList<String>());
			}
			for(int i=1;i<array.length;i++)
			{
				if(array[i].charAt(0)=='-')
				{
					if(array[i].charAt(1)=='s')
					{
						if(i+2<array.length)
						{
							int position = array[i++].charAt(2)-'0'-1;
							String op=calcop(array[i++]);
							System.out.println(op);
							if(position>select.size())
								throw new Exception("Column doesn't exists");
							select.get(position).add(op);
							select.get(position).add(array[i]);
						}
						else
						{
							throw new Exception("Select condition not full");
						}
					}
					else
					{
						if(array[i].charAt(1)=='p')
						{
							project[array[i].charAt(2)-'0'-1]=true;
						}
						else
						{
							throw new Exception("Wrong query");
						}
					}
				}
				else
				{
					throw new Exception("wrong query");
				}
			}
			int c=0;
			//storing which columns to display.
			for(int i=0;i<project.length;i++)
			{
				if(project[i])
					c++;
			}
			if(c==0)
			{
				Arrays.fill(project, true);
				c=project.length;
			}
			File file =new File(output);
			boolean returned;
			//Deleting the output file if it already present.
			if(file.exists())
			{
				returned = file.delete();
				System.out.println(returned);
			}
			StringWriter s= new StringWriter();
			String record[]=new String[headerData.size()];

			// Taking each record and checking whether it matches the selection condition or not and writing if it matches.
			try
			{
				while(heap.readpointer<heap.f.length())
				{
					boolean ch=false;

					for(int j=0;j<headerData.size();j++)
					{
						String data = datatypes[headerData.get(j).type].read(headerData.get(j).length);

						int i=data.indexOf('~');
						if(i!=-1)
							data=data.substring(0,i);

						record[j]=data;

						for(int k=0;k<select.get(j).size();k+=2)
						{
							int com = datatypes[headerData.get(j).type].compares(record[j],select.get(j).get(k+1) );
							int length=select.get(j).get(k).length();
							String regex;
							String str;
							str=com+"";
							if(length==2)
								regex=select.get(j).get(k).charAt(0)+""+"|"+select.get(j).get(k).charAt(1)+"";
							else
								regex=select.get(j).get(k).charAt(0)+"";

							if(!str.matches(regex))
							{
								ch=true;
							}
						}
					}

					if(!ch)
					{
						int dis=0;
						for(int t=0;t<project.length;t++)
						{
							if(project[t])
							{
								s.writeString(record[t],output);
								dis++;
								if(dis!=c)
									s.writeString(",",output);
							}

						}
						s.writeString("\n",output);
					}


				}
			}
			catch(Exception e)
			{
				System.out.println("Invalid select condition");
			}


		}
		catch(Exception e)
		{
			System.out.println(e);
		}

	}
}
